iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0

昨天我們已經按照時間去新增我們的資料了,也得到列表啦,那麼我們今天就要來建立點擊事件,因為如果只有顯示,但是沒辦法到該頁面的話,那就沒辦法聊到天啦,正所謂看得到吃不到,就沒有意義啦!

但是..... 我們會有一個很大的問題就是,當我們今天從A畫面到ChatRoom的時候,我們的資料是從Invitation的資料丟進去的(來源是Firestore),但是如果今天使用者直接想要找我們之前聊過的人聊天呢? 那它不就沒辦法拿到之前的資料啦?

還記得我們昨天有新增一個LastMessage的dataClass嗎? 太棒了,我們就直接從這邊拿到資料吧!!

package com.example.petsmatchingapp.model

data class LastMessage(

    val display_name: String = "",
    val display_image: String = "",
    val display_id: String = "",
    val message: String = "",
    val send_time: Long? = 0
)

★這裡面的資料都是我們應該要顯示的資訊,所以我們可以透過id來找Firestore相關的照片跟名字(因為我們在寄送訊息的時候會需要accepter的detail),而這些資訊之前是透過invitation的detail來拿到的。

1.透過user_id拿到聊天對象的資料吧!!

雖然我覺得目前這樣的寫法不是很好,因為這樣代表只要某user拿到其它人的userId,就可以看到它的資訊。之後有空再回來改!!

//一樣想入livedata,好讓我們之後可以觀察
private val _selectedUserDetail = MutableLiveData<User>()
val selectedUserDetail: LiveData<User>
get() = _selectedUserDetail


fun findUserDetailByID(user_id: String){
        Firebase.firestore.collection(Constant.USER).document(user_id).get()
            .addOnSuccessListener {
                _selectedUserDetail.postValue(it.toObject(User::class.java))
            }
            .addOnFailureListener {

            }
    }

接下來,我們就回到NotificationAdapter來設定onClick事件。

我們在onBindViewHolder新增

holder.itemView.setOnClickListener {
            fragment.goChatRoom(model)
        }

並且回到Notification來新增我們的導航跟把LastMessage傳進去viewModel

fun goChatRoom(lastMessage: LastMessage){
    chatViewModel.saveSelectedChatRoomUserDetail(lastMessage) findNavController().navigate(R.id.action_navigation_notifications_to_chatRoomFragment)

  }

★ 這邊也要記得在我們的Navigation連連看喔,不然找不到ID

來viewModel建立funtion,讓我們儲存UserDetail

private val _selectedChatRoomUserDetail = MutableLiveData<LastMessage>()
val selectedChatRoomUserDetail: LiveData<LastMessage>
get() = _selectedChatRoomUserDetail


fun saveSelectedChatRoomUserDetail(lastMessage: LastMessage){
        _selectedChatRoomUserDetail.postValue(lastMessage)
    }

然後來到我們的ChatRoomFragment來透過我們的ID,得到我們聊天者的Detail,別忘記要新增判斷喔,不然如果我們的使用者直接從InvitationsDetail進入的話,那我們就拿不到selectedChatRoomUserDetail的值啦!!

if(chatViewModel.fromDetail.value == false){
            accountViewModel.findUserDetailByID(chatViewModel.selectedChatRoomUserDetail.value!!.display_id)
        }

2.判斷是從哪個頁面進去的

就跟剛剛提到的一樣,我們從不同Fragment進去的時候,我們的資料來源不一樣,那我們可以怎麼辦呢?!
於是乎,我們就用Flag來判斷,我們首先在ChatViewModel來新增以下

private val _fromDetail = MutableLiveData<Boolean>()
val fromDetail: LiveData<Boolean>
get() = _fromDetail


fun setFromDetailOrNot(boolean: Boolean){
    _fromDetail.postValue(boolean)
    }

然後再這個兩Fragment來修改它的值,既然它的取名是fromDetail的話,我們當然要在InvitationDetailFragment的時候更改它阿,並且改成true

chatViewModel.setFromDetailOrNot(true)

反之,在NotificationFragment我們把它設成false

3.修改Read/Writev訊息的資料來源

基本上如果是從Detail的話,我們就不用修正,但是如果是從NotificationFragment的話,我們就需要作出修正! 我們直接丟剛剛透過點擊事件得到的資料。

修改Read

if (chatViewModel.fromDetail.value == true) {
            chatViewModel.messageValueListener(
                this,
                accountViewModel.userDetail.value!!.id,
                matchingViewModel.selectedInvitation.value!!.user_id
            )
            matchingViewModel.selectedInvitation.value?.user_name?.let {
                binding.tvChatRoomAcceptUserName.text = it
            }
        } else {
            chatViewModel.messageValueListener(
                this,
                accountViewModel.userDetail.value!!.id,
                chatViewModel.selectedChatRoomUserDetail.value!!.display_id
            )
            binding.tvChatRoomAcceptUserName.text = chatViewModel.selectedChatRoomUserDetail.value!!.display_name
        }

修改write,我們只要修改來自Notification的資料,並把accept的資料都改成剛剛透過id,找到的Detail。

var message = Message()
        if (chatViewModel.fromDetail.value == true){
            message = Message(
                user_name = accountViewModel.userDetail.value!!.name,
                message = binding.edChatRoomInputMessage.text.toString().trim(),
                send_user_id = accountViewModel.userDetail.value!!.id,
                accept_user_id = matchingViewModel.selectedInvitation.value!!.user_id,
                send_user_image = accountViewModel.userDetail.value!!.image,
                send_user_name = accountViewModel.userDetail.value!!.name,
                time = ServerValue.TIMESTAMP,
                accept_user_image = matchingViewModel.selectedInvitation.value?.user_image,
                accept_user_name = matchingViewModel.selectedInvitation.value?.user_name
            )
        }else{
            message = Message(
                user_name = accountViewModel.userDetail.value!!.name,
                message = binding.edChatRoomInputMessage.text.toString().trim(),
                send_user_id = accountViewModel.userDetail.value!!.id,
                send_user_image = accountViewModel.userDetail.value!!.image,
                send_user_name = accountViewModel.userDetail.value!!.name,
                accept_user_name = accountViewModel.selectedUserDetail.value!!.name,
                accept_user_image = accountViewModel.selectedUserDetail.value!!.image,
                accept_user_id = accountViewModel.selectedUserDetail.value!!.id,
                time = ServerValue.TIMESTAMP,

            )
        }

好啦,這樣就大功告成啦!

4.ActionBar跟BottomNavigation隱藏/秀出來

之前我們是透過Invitation來進入chatRoom,所以我們在InvitationDetaiFragment就已經處理啦,那我們這時候如果直接從NotificationFragment,我們就需要再處理啦!

一樣新增,並在onCreateView呼叫它

private fun dismissActivityActionBarAndBottomNavigationView() {
        val activityInstance = this.activity as MatchingActivity
        activityInstance.supportActionBar?.hide()
        activityInstance.findViewById<BottomNavigationView>(R.id.nav_view).visibility = View.GONE

    }

回到NotificationFragment,新增它並且在onResume呼叫它

private fun showActionBarAndBottomNavigation() {

    if (requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility == View.GONE) {
      requireActivity().findViewById<BottomNavigationView>(R.id.nav_view).visibility =
        View.VISIBLE
    }

    val activityInstance = this.activity as MatchingActivity
    activityInstance.supportActionBar?.show()

  }

大功告成啦!

成品如下!!
day21.finished


上一篇
【day20】創建對象列表(上)
下一篇
【day22】FCM雲端通訊測試
系列文
30天建立寵物約散App-Android新手篇30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言